<?php

namespace nimo\common\models;

use Baum\Node;
use Baum\Move;
use nimo\common\develop\Profiler;

class NodeMove extends Move {

  // ------------------------------
  // baum move function
  // ------------------------------
  protected function parentId() {
    if ( $this->position == 'child' )
      return $this->target->getKeyWithoutScope();
    return $this->target->getParentId();
  }

  protected function resolveNode($node) {
  	if ( $node instanceof \Baum\Node )  {
  		return $node->reload();
  	}
  	$query = $this->node->newNestedSetQuery();
  	$keys = $this->node->getKeyWithScope($node);
  	foreach ($keys as $key => $value) {
  		$query->where($key, '=', $value);
  	}
  	$instance = $query->first();
  	return $instance;
  }
  public function updateStructure() {
    list($a, $b, $c, $d) = $this->boundaries();

    $connection = $this->node->getConnection();
    $grammar    = $connection->getQueryGrammar();

    $currentId      = $this->quoteIdentifier($this->node->getKeyWithoutScope());
    $parentId       = $this->quoteIdentifier($this->parentId());
    $leftColumn     = $this->node->getLeftColumnName();
    $rightColumn    = $this->node->getRightColumnName();
    $parentColumn   = $this->node->getParentColumnName();
    $wrappedLeft    = $grammar->wrap($leftColumn);
    $wrappedRight   = $grammar->wrap($rightColumn);
    $wrappedParent  = $grammar->wrap($parentColumn);
    $wrappedId      = $grammar->wrap($this->node->getKeyNameWithoutScope());

    $lftSql = "CASE
      WHEN $wrappedLeft BETWEEN $a AND $b THEN $wrappedLeft + $d - $b
      WHEN $wrappedLeft BETWEEN $c AND $d THEN $wrappedLeft + $a - $c
      ELSE $wrappedLeft END";

    $rgtSql = "CASE
      WHEN $wrappedRight BETWEEN $a AND $b THEN $wrappedRight + $d - $b
      WHEN $wrappedRight BETWEEN $c AND $d THEN $wrappedRight + $a - $c
      ELSE $wrappedRight END";

    $parentSql = "CASE
      WHEN $wrappedId = $currentId THEN $parentId
      ELSE $wrappedParent END";

    return $this->node
                ->newNestedSetQuery()
                ->where(function($query) use ($leftColumn, $rightColumn, $a, $d) {
                  $query->whereBetween($leftColumn, array($a, $d))
                        ->orWhereBetween($rightColumn, array($a, $d));
                })
                ->update(array(
                  $leftColumn   => $connection->raw($lftSql),
                  $rightColumn  => $connection->raw($rgtSql),
                  $parentColumn => $connection->raw($parentSql)
                ));
  }
}
